package zencstudio.sgrealtor.service;

import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

import zencstudio.sgrealtor.model.Contact;
import zencstudio.sgrealtor.model.Course;
import zencstudio.sgrealtor.model.CourseRegisterRequest;
import zencstudio.sgrealtor.model.Feedback;
import zencstudio.sgrealtor.model.FeedbackTemplate;
import zencstudio.sgrealtor.model.GCMRegisterRequest;
import zencstudio.sgrealtor.model.ListCourse;
import zencstudio.sgrealtor.model.ListProperty;
import zencstudio.sgrealtor.model.LoanCalculateRequest;
import zencstudio.sgrealtor.model.POSTResponse;
import zencstudio.sgrealtor.model.Property;
import zencstudio.sgrealtor.model.PropertyDetail;
import zencstudio.sgrealtor.model.PropertyLocation;
import zencstudio.sgrealtor.model.PropertyType;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.google.android.gms.maps.model.LatLng;

public class WireFrameService implements IWireFrameService{

	@Override
	public <T> T get(String url, Class type) {
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();
		ResponseEntity<T> responseEntity =null;
		try{
			requestEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, type);
		}
		catch(Exception ex){
			ex.printStackTrace();
		}
		return responseEntity.getBody();
	}

	@Override
	public <T> List<T> getList(String url, Class type) {
		// TODO Auto-generated method stub
		return null;
				
	}

	@Override
	public List<Property> getProperties(int offset, int count) {
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json",Charset.forName("UTF-8"))));
		//requestHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();

		ResponseEntity<ListProperty> responseEntity =null;
		String url = RestTemplateService.getInstance().getServiceConfig().getUrlListProperty();
		responseEntity = restTemplate.exchange(String.format(url,offset,count),
				HttpMethod.GET, requestEntity, ListProperty.class);

		List<Property> listProperty = Arrays.asList(responseEntity.getBody()
				.getListP());
		return listProperty;

	}

	@Override
	public PropertyDetail getProperty(int id) {
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","xml")));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();
		ResponseEntity<PropertyDetail> responseEntity =null;		
		String url = RestTemplateService.getInstance().getServiceConfig().getUrlProperty();
		responseEntity = restTemplate.exchange(String.format(url, id), HttpMethod.GET, requestEntity, PropertyDetail.class);	
		return responseEntity.getBody();		
	}

	@Override
	public ListCourse getCourses(int offset, int count) {
		// TODO Auto-generated method stub
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json",Charset.forName("UTF-8"))));
		//requestHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();

		ResponseEntity<ListCourse> responseEntity =null;
		
		String url = RestTemplateService.getInstance().getServiceConfig().getUrlListCourse();
		responseEntity = restTemplate.exchange(String.format(url,offset,count), HttpMethod.GET, requestEntity, ListCourse.class);
		return responseEntity.getBody();
	}

	@Override
	public Course getCourse(int id) {
		// TODO Auto-generated method stub
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","xml")));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();
		ResponseEntity<Course> responseEntity =null;		
		String url = RestTemplateService.getInstance().getServiceConfig().getUrlCourse();
		responseEntity = restTemplate.exchange(String.format(url, id), HttpMethod.GET, requestEntity, Course.class);	
		return responseEntity.getBody();
	}

	@Override
	public List<Property> getSearchProperty(String url) {
		// TODO Auto-generated method stub
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json",Charset.forName("UTF-8"))));
		//requestHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();

		ResponseEntity<ListProperty> responseEntity =null;
		//String url = RestTemplateService.getInstance().getServiceConfig().getUrlListProperty();
		//String url = "http://rest-service.guides.spring.io/greeting";
		//String url = RestTemplateService.getInstance().getServiceConfig().getUrlProperty();
		//responseEntity = restTemplate.exchange(String.format(url), HttpMethod.GET, requestEntity, ListProperty.class);
		//responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Greeting.class);	
		String urlService = RestTemplateService.getInstance().getServiceConfig().getUrlSearchProperty();
		responseEntity = restTemplate.exchange(String.format(urlService,url),
				HttpMethod.GET, requestEntity, ListProperty.class);

		List<Property> listProperty = Arrays.asList(responseEntity.getBody()
				.getListP());
		return listProperty;
	}
	@Override
	public POSTResponse registerCourse(CourseRegisterRequest course) {
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.set("Connection", "Close");
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));
		HttpEntity<CourseRegisterRequest> requestEntity = new HttpEntity<CourseRegisterRequest>(course,requestHeaders);		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();
		ResponseEntity<POSTResponse> responseEntity =null;
		String urlService = RestTemplateService.getInstance().getServiceConfig().getUrlRegisterCourse();
		responseEntity = restTemplate.exchange(urlService,HttpMethod.POST, requestEntity, POSTResponse.class);
		return responseEntity.getBody();
	}
	@Override
	public POSTResponse sendContact(Contact contact) {
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.set("Connection", "Close");
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));
		HttpEntity<Contact> requestEntity = new HttpEntity<Contact>(contact,requestHeaders);		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();
		ResponseEntity<POSTResponse> responseEntity =null;
		String urlService = RestTemplateService.getInstance().getServiceConfig().getUrlContactUs();
		responseEntity = restTemplate.exchange(urlService,HttpMethod.POST, requestEntity, POSTResponse.class);
		return responseEntity.getBody();
	}

	@Override
	public List<FeedbackTemplate> getFeedbackTemplate() {
		// TODO Auto-generated method stub
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json",Charset.forName("UTF-8"))));
		//requestHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();

		ResponseEntity<FeedbackTemplate[]> responseEntity =null;
		//String url = RestTemplateService.getInstance().getServiceConfig().getUrlListProperty();
		//String url = "http://rest-service.guides.spring.io/greeting";
		//String url = RestTemplateService.getInstance().getServiceConfig().getUrlProperty();
		//responseEntity = restTemplate.exchange(String.format(url), HttpMethod.GET, requestEntity, ListProperty.class);
		//responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Greeting.class);	
		String urlService = RestTemplateService.getInstance().getServiceConfig().getUrlGetTemplate();
		responseEntity = restTemplate.exchange(urlService,HttpMethod.GET, requestEntity, FeedbackTemplate[].class);

		return Arrays.asList(responseEntity.getBody());
	}

	@Override
	public POSTResponse sendFeedback(Feedback feedback) {
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.set("Connection", "Close");
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));
		HttpEntity<Feedback> requestEntity = new HttpEntity<Feedback>(feedback,requestHeaders);		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();
		ResponseEntity<POSTResponse> responseEntity =null;
		String urlService = RestTemplateService.getInstance().getServiceConfig().getUrlFeedBack();
		responseEntity = restTemplate.exchange(urlService,HttpMethod.POST, requestEntity, POSTResponse.class);
		return responseEntity.getBody();
	}

	@Override
	public List<PropertyType> getPropertyTypes() {
		// TODO Auto-generated method stub
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json",Charset.forName("UTF-8"))));
		//requestHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();

		ResponseEntity<PropertyType[]> responseEntity =null;

		String url = RestTemplateService.getInstance().getServiceConfig().getUrlListTypes();
		responseEntity = restTemplate.exchange(String.format(url), HttpMethod.GET, requestEntity, PropertyType[].class);
		List<PropertyType > types = new ArrayList<PropertyType>();
		types.addAll(Arrays.asList(responseEntity.getBody()));
		return types;		
	}

	@Override
	public List<PropertyLocation> getPropertyLocations() {
		// TODO Auto-generated method stub
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json",Charset.forName("UTF-8"))));
		//requestHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();

		ResponseEntity<PropertyLocation[]> responseEntity =null;
	
		String url = RestTemplateService.getInstance().getServiceConfig().getUrlListLocations();
		responseEntity = restTemplate.exchange(String.format(url), HttpMethod.GET, requestEntity, PropertyLocation[].class);
		List<PropertyLocation> locations = new ArrayList<PropertyLocation>();
		locations.addAll(Arrays.asList(responseEntity.getBody()));
		return locations;
	}

	@Override
	public Bitmap calculate(LoanCalculateRequest request) throws Exception {
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.set("Connection", "Close");
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));
		HttpEntity<LoanCalculateRequest> requestEntity = new HttpEntity<LoanCalculateRequest>(request,requestHeaders);		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();
		ResponseEntity<Resource> responseEntity =null;
		String urlService = RestTemplateService.getInstance().getServiceConfig().getUrlLoanCalculate();
		responseEntity = restTemplate.exchange(String.format(urlService, request.amount,request.rate,request.term,request.screenWidth), HttpMethod.GET, requestEntity, Resource.class);
		Bitmap bitmap = BitmapFactory.decodeStream(responseEntity.getBody().getInputStream());
		return bitmap;
	}

	@Override
	public LatLng getGoogleLocation(String address)
			throws Exception {
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json",Charset.forName("UTF-8"))));
		//requestHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();

		ResponseEntity<String> responseEntity =null;
	
		String url = RestTemplateService.getInstance().getServiceConfig().getUrlGoogleLocationService();
		responseEntity = restTemplate.exchange(String.format(url,address), HttpMethod.GET, requestEntity, String.class);			

		XPathFactory factory = XPathFactory.newInstance();
	    XPath xpath = factory.newXPath();
	    StringReader reader = new StringReader(responseEntity.getBody());
	    InputSource inputXml = new InputSource(reader);
	    Node node =  (Node) xpath.evaluate("GeocodeResponse/result/geometry/location", inputXml, XPathConstants.NODE);
	    double lat = (Double)  xpath.evaluate("lat", node, XPathConstants.NUMBER);
	    double lng = (Double)  xpath.evaluate("lng", node, XPathConstants.NUMBER);
	    reader.close();
		return new LatLng(lat, lng);
	}

	@Override
	public POSTResponse registerGCMKey(GCMRegisterRequest request)
			throws Exception {
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.set("Connection", "Close");
		requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));
		HttpEntity<GCMRegisterRequest> requestEntity = new HttpEntity<GCMRegisterRequest>(request,requestHeaders);		
		RestTemplate restTemplate = RestTemplateService.getInstance().getRestTemplate();
		ResponseEntity<POSTResponse> responseEntity =null;
		String urlService = RestTemplateService.getInstance().getServiceConfig().getGCMServerRegisterUrl();
		responseEntity = restTemplate.exchange(urlService,HttpMethod.POST, requestEntity, POSTResponse.class);
		return responseEntity.getBody();
	}
	
}
